\myparagraph{\Optimizing MSVC 2010}

\lstinputlisting[caption=\Optimizing MSVC 2010,style=customasmx86]{patterns/12_FPU/3_comparison/x86/MSVC_Ox/MSVC_RU.asm}

\myindex{x86!\Instructions!FCOM}
\FCOM отличается от \FCOMP тем, что просто сравнивает значения и оставляет стек в том же состоянии. 
В отличие от предыдущего примера, операнды здесь в обратном порядке. 
Поэтому и результат сравнения в \CThreeBits будет отличаться:

\begin{itemize}
\item Если $a>b$, то биты \CThreeBits должны быть выставлены так: 0, 0, 0.
\item Если $b>a$, то биты будут выставлены так: 0, 0, 1.
\item Если $a=b$, то биты будут выставлены так: 1, 0, 0.
\end{itemize}
% TODO: table?

Инструкция \INS{test ah, 65} как бы оставляет только два бита~--- \Cthree и \Czero. 
Они оба будут нулями, если $a>b$: в таком случае переход \JNE не сработает. 
\myindex{ARM!\Instructions!FSTP}
Далее имеется инструкция \INS{FSTP ST(1)}~--- эта инструкция копирует 
значение \ST{0} в указанный операнд и выдергивает одно значение из стека. В данном случае, 
она копирует \ST{0} 
(где сейчас лежит~\GTT{\_a})~в~\ST{1}. 
После этого на вершине стека два раза лежит~\GTT{\_a}. Затем одно значение выдергивается. 
После этого в \ST{0} остается~\GTT{\_a} и функция завершается.

Условный переход \JNE сработает в двух других случаях: если $b>a$ или $a=b$. 
\ST{0} скопируется в \ST{0} (как бы холостая операция). 
Затем одно значение из стека вылетит и на вершине стека останется то, что 
до этого лежало в \ST{1} (то~есть~\GTT{\_b}). И функция завершится. 
Эта инструкция используется здесь видимо потому что в FPU 
нет другой инструкции, которая просто выдергивает 
значение из стека и выбрасывает его.

\input{patterns/12_FPU/3_comparison/x86/MSVC_Ox/olly_RU.tex}
